home *** CD-ROM | disk | FTP | other *** search
- #ifndef lint
- static char *RCS_init_c = "$Id: init.c,v 1.3 90/04/23 14:41:11 rogers Exp $";
- #endif
-
- /* --------------------
- vmail -- init.c
-
- Initialisation routines - setting ttystate, finding valid folders,
- trapping signals.
-
- Ttystate is controlled by a mix of curses and ioctl. For simplicity,
- initial setups are done with curses. Curses is also used for basic
- screen manipulation. However, for speed ioctl is used in switching
- in and out of normal terminal state.
-
- Copyright (C) J. Zobel, University of Melbourne, October 1987.
- -------------------- */
-
- #include "defs.h"
- #include <signal.h>
-
- static struct sgttyb tty, t_tty; /* for holding tty state */
- static struct tchars chrs, t_chrs;
- static struct ltchars lchrs, t_lchrs;
-
- static char termcap[1024], /* termcap entry */
- *cur_folder; /* initial current folder */
-
- sig_type tstp(), tint();
-
- /* --------------------
- Start-up routine - set terminal control, signals, etc.
- -------------------- */
- void
- init(argc, argv)
- int argc;
- char **argv;
- {
- folder ftmp, find_mail();
- char *pargv[20], /* argv from profile */
- *profile = (char *) NULL, /* location of MH profile */
- *home = (char *) NULL, /* home directory */
- *term = (char *) NULL; /* terminal type */
- int pargc = 0; /* argc from profile */
-
- get_home(&home);
- get_env(&term, &profile, home);
- (void)tgetent(termcap, term);
- cols = tgetnum("co");
- /* lines holds no. of lines for headers, ie "li" less STATUS, TITLE */
- lines = tgetnum("li") - 2;
- (void)ioctl(0, TIOCGETP, (caddr_t)&tty);
- (void)ioctl(0, TIOCGETP, (caddr_t)&chrs);
- (void)ioctl(0, TIOCGETP, (caddr_t)&lchrs);
-
- read_profile(&pargc, pargv, profile, home);
- process_args(pargc, pargv);
- find_folders();
- mark_valid_folders(pargc, pargv);
- /* give precedence to command line args => process second */
- mark_valid_folders(argc, argv);
- for(ftmp=folders ; ftmp != (folder) NULL ;)
- if(ftmp->valid)
- ftmp = find_mail(ftmp, true);
- else
- ftmp = ftmp->next;
- if(curflr->valid == EMPTY) {
- (void)printf("%s: folder empty.\n", curflr->name);
- exit(1);
- }
- /* find last instance of initial folder */
- LAST_OF_NAME(curflr);
- curmail = curflr->mail;
-
- (void)initscr();
- (void)crmode();
- (void)noecho();
- (void)nonl();
-
- (void)signal(SIGTSTP, tstp);
- (void)signal(SIGINT, tint);
-
- (void)ioctl(0, TIOCGETP, (caddr_t)&t_tty);
- (void)ioctl(0, TIOCGETP, (caddr_t)&t_chrs);
- (void)ioctl(0, TIOCGETP, (caddr_t)&t_lchrs);
-
- y = FIRST;
- display_page();
- }
-
-
- /* --------------------
- Find user name, home directory.
- -------------------- */
- void
- get_home(home)
- char **home;
- {
- struct passwd *pwent, *getpwuid();
- #ifdef vax
- uid_t getuid();
- #endif
-
- pwent = getpwuid((int)getuid());
- *home = NEWSTR(strlen(pwent->pw_dir)+1);
- (void)strcpy(*home, pwent->pw_dir);
- if(access(*home, R_OK | W_OK | X_OK)) {
- (void)printf("%s: no permissions.\n", *home);
- exit(1);
- }
- user = NEWSTR(strlen(pwent->pw_name)+1);
- (void)strcpy(user, pwent->pw_name);
- }
-
-
- /* --------------------
- Find pager, editor, shell, terminal type, MH profile - defaults are PAGER,
- EDITOR, SHELL, none, PROFILE. Set by PAGER, EDITOR, SHELL, TERM, MH
- environment variables.
- -------------------- */
- void
- get_env(term, profile, home)
- char **term, **profile, *home;
- {
- char **tmp;
-
- for(tmp = environ ; *tmp != (char *) NULL ; tmp++)
- if(!strncmp("PAGER=", *tmp, 6)) {
- pager = NEWSTR(strlen(*tmp)-4);
- (void)strcpy(pager, *tmp+6);
- } else if(!strncmp("EDITOR=", *tmp, 7)) {
- editor = NEWSTR(strlen(*tmp)-5);
- (void)strcpy(editor, *tmp+7);
- } else if(!strncmp("SHELL=", *tmp, 6)) {
- shell = NEWSTR(strlen(*tmp)-4);
- (void)strcpy(shell, *tmp+6);
- } else if(!strncmp("TERM=", *tmp, 5)) {
- *term = NEWSTR(strlen(*tmp)-3);
- (void)strcpy(*term, *tmp+5);
- } else if(!strncmp("MH=", *tmp, 3)) {
- *profile = NEWSTR(strlen(*tmp)-1);
- (void)strcpy(*profile, *tmp+3);
- }
- if(*term == (char *) NULL) {
- (void)printf("Terminal type unknown\n");
- exit(1);
- }
- if(*profile == (char *) NULL) {
- *profile = NEWSTR(strlen(home)+strlen(PROFILE)+2);
- (void)sprintf(*profile, "%s/%s", home, PROFILE);
- }
- if(pager == (char *) NULL) {
- pager = NEWSTR(strlen(PAGER)+1);
- (void)strcpy(pager, PAGER);
- }
- if(shell == (char *) NULL) {
- shell = NEWSTR(strlen(SHELL)+1);
- (void)strcpy(shell, SHELL);
- }
- if(editor == (char *) NULL) {
- editor = NEWSTR(strlen(EDITOR)+1);
- (void)strcpy(editor, EDITOR);
- }
- }
-
-
- static char argkeep[LEN]; /* storage for args from profile */
-
- /* --------------------
- Find mail directory, current-folder, context, default options.
- -------------------- */
- void
- read_profile(pargc, pargv, profile, home)
- int *pargc;
- char **pargv, *profile, *home;
- {
- FILE *fp, *fopen();
- char str[LEN], *ptr, iscontext[LEN], *index(), *next_token();
-
- if((fp = fopen(profile, "r")) == (FILE *) NULL) {
- (void)printf("Profile: %s: cannot open.\n", profile);
- exit(1);
- }
- *iscontext = '\0';
- while(fgets(str, LEN, fp) != (char *) NULL) {
- /* get entries from profile */
- if(lstrncmp("context:", str, 8) == 0 && *(ptr=str+8) != '\0') {
- squash(str);
- (void)strcpy(iscontext, str+8);
- } else if(lstrncmp("vmail:", str, 6) == 0 && *(ptr=str+6) != '\0') {
- for( ; *ptr == ' ' || *ptr == '\t' ; ptr++)
- ;
- *index(ptr, '\n') = '\0';
- (void)strcpy(argkeep, ptr);
- for(ptr=argkeep ; *ptr != '\0' ; ) {
- pargv[(*pargc)++] = ptr;
- ptr = next_token(ptr);
- }
- } else if(lstrncmp("path:", str, 5) == 0 && *(ptr=str+5) != '\0') {
- squash(str);
- if(*ptr == '/') { /* full pathname */
- mail_dir = NEWSTR(strlen(ptr)+1);
- (void)strcpy(mail_dir, ptr);
- } else {
- mail_dir = NEWSTR(strlen(home)+strlen(ptr)+1);
- (void)sprintf(mail_dir, "%s/%s", home, ptr);
- }
- } else if(lstrncmp("folder-protect:", str, 15) == 0 &&
- *(str+15) != '\0') {
- squash(str);
- folder_protect = atoo(str+15);
- } else if(lstrncmp("current-folder:", str, 15) == 0 &&
- *(str+15) != '\0') {
- squash(str);
- cur_folder = NEWSTR(strlen(str+15)+1);
- (void)strcpy(cur_folder, str);
- }
- }
- (void)fclose(fp);
- if(mail_dir == (char *) NULL) {
- mail_dir = NEWSTR(strlen(home)+strlen(MAILDIR)+2);
- (void)sprintf(mail_dir, "%s/%s", home, str+6);
- }
- if(access(mail_dir, R_OK | W_OK | X_OK)) {
- (void)printf("%s: no permissions.\n", mail_dir);
- exit(1);
- }
- if(*iscontext == '\0')
- (void)strcpy(iscontext, CONTEXT);
- context = NEWSTR(strlen(mail_dir)+strlen(iscontext)+2);
- (void)sprintf(context, "%s/%s", mail_dir, iscontext);
- if(access(context, R_OK | W_OK)) {
- (void)printf("%s: no permissions.\n", context);
- exit(1);
- }
- if(cur_folder == (char *) NULL)
- cur_folder = CURFOL;
- }
-
-
- /* --------------------
- Squash spaces, tabs, newlines out of given string.
- -------------------- */
- void
- squash(str)
- char *str;
- {
- int i, j;
-
- for(i=0, j=0 ; (str[j] = str[i]) != '\0' ; i++)
- if(str[j] != ' ' && str[j] != '\t' && str[j] != '\n')
- j++;
- }
-
-
- /* --------------------
- Mark folders as specified by setenv, command line. At startup, default
- is for only active folder to be cur_folder.
- -------------------- */
- void
- mark_valid_folders(argc, argv)
- int argc;
- char **argv;
- {
- char *name;
- folder f;
-
- name = cur_folder;
- /* find valid folders - mark all folders from argv as valid */
- for(; argc > 0 ; argc--, argv++)
- if(**argv == '+') /* startup folder */
- name = (*argv) + 1;
- else if(**argv != '-') { /* not a flag */
- GOTO_NAME(f, *argv);
- if(f == (folder) NULL)
- (void)printf("Warning: no such folder as %s\n", *argv);
- else
- f->valid = true;
- }
- GOTO_NAME(f, name);
- if(f == (folder) NULL) {
- (void)printf("%s does not exist\n", name);
- exit(1);
- }
- f->valid = true;
- curflr = f;
- }
-
-
- /* --------------------
- Reset terminal, clean up.
- -------------------- */
- void
- to_normal()
- {
- move(lines+FIRST-1, 0);
- refresh();
- no_control();
- (void)printf("\n");
- }
-
-
- /* --------------------
- Reset terminal.
- -------------------- */
- void
- no_control()
- {
- int x, y;
- char c;
-
- #ifdef STANDOUT_CLEANUP
- /*
- * The following code forces curses to issue a standend if it has
- * one pending.
- */
-
- getyx(stdscr, y, x);
- c = inch() & 0x7f;
- if (c == 'a') {
- addch('b');
- }
- else {
- addch('a');
- }
- move(y, x);
- refresh();
- move(y, x);
- addch(c);
- move(y, x);
- refresh();
- #endif
-
- (void)ioctl(0, TIOCSETP, (caddr_t)&tty);
- (void)ioctl(0, TIOCSETP, (caddr_t)&chrs);
- (void)ioctl(0, TIOCSETP, (caddr_t)&lchrs);
- }
-
-
- /* --------------------
- Set terminal.
- -------------------- */
- void
- to_control()
- {
- (void)ioctl(0, TIOCSETP, (caddr_t)&t_tty);
- (void)ioctl(0, TIOCSETP, (caddr_t)&t_chrs);
- (void)ioctl(0, TIOCSETP, (caddr_t)&t_lchrs);
- }
-
-
- #define mask(s) (1 << ((s)-1))
-
- /* --------------------
- Trap for ^Z.
- -------------------- */
- sig_type
- tstp()
- {
- int x, y;
-
- getyx(curscr, y, x);
- to_normal();
- fix_mh();
-
- (void)signal(SIGTSTP, SIG_DFL);
- (void)sigsetmask(sigblock(0) &~ mask(SIGTSTP));
- (void)kill(0, SIGTSTP);
- (void)sigblock(mask(SIGTSTP));
- (void)signal(SIGTSTP, tstp);
-
- if(top_level) {
- to_control();
- touchwin(curscr);
- (void)wmove(curscr, y, x);
- (void)wrefresh(curscr);
- }
- }
-
-
- /* --------------------
- Trap for ^?.
- -------------------- */
-
- sig_type
- tint()
- {
- touchwin(stdscr);
- addstatus("-- interrupt --", true);
- longjmp(env, 0); /* jump to main */
- }
-
-
- /* --------------------
- Convert an ascii string to octal.
- -------------------- */
- int
- atoo(str)
- char *str;
- {
- int i;
-
- for(; *str < '0' && *str > '7' ; str++)
- ;
- for(i=0 ; *str >= '0' && *str <= '7' ; str++)
- i = i*8 + *str - '0';
- return(i);
- }
-
-
- /* --------------------
- Update MH environment - context and current mail item of current folder.
- -------------------- */
- fix_mh()
- {
- char str[LEN], buf[20];
-
- update(context, "Current-Folder:", curflr->name, 15);
- (void)sprintf(str, "%s/%s/%s", mail_dir, curflr->name, SEQU);
- (void)sprintf(buf, "%d", curmail->number);
- update(str, "cur:", buf, 4);
- }
-
-
- /* --------------------
- Update file, replacing line beginning with match of len by "match new".
- -------------------- */
- update(file, match, new, len)
- char *file, *match, *new;
- int len;
- {
- FILE *fp, *tmp, *fopen();
- bool change = false;
- char *mktemp(), *fgets();
- char str[LEN], *name = mktemp("/tmp/vmail.XXXXXX");
-
- if((fp = fopen(file, "r")) == (FILE *) NULL) {
- if((fp = fopen(file, "w+")) == (FILE *) NULL)
- (void)printf("Can't open %s for writing\n", file);
- else {
- (void)fprintf(fp, "%s %s\n", match, new);
- (void)fclose(fp);
- }
- } else {
- if((tmp = fopen(name, "w+")) == (FILE *) NULL)
- (void)printf("Can't open %s\n", file);
- else {
- while(fgets(str, LEN, fp) != (char *) NULL)
- if(lstrncmp(str, match, len) == 0) {
- change = true;
- (void)fprintf(tmp, "%s %s\n", match, new);
- } else
- (void)fprintf(tmp, "%s", str);
- if(! change)
- (void)fprintf(tmp, "%s %s\n", match, new);
- (void)fclose(fp);
- (void)fclose(tmp);
- if((fp = fopen(file, "w+")) == (FILE *) NULL)
- (void)printf("Can't open %s for writing\n", file);
- else {
- tmp = fopen(name, "r");
- while(fgets(str, LEN, tmp) != (char *) NULL)
- (void)fprintf(fp, "%s", str);
- (void)fclose(fp);
- (void)fclose(tmp);
- (void)unlink(name);
- }
- }
- }
- }
-